const { resolve } = require("path");

// 打乱数组 (逻辑对后，看代码的每一步骤)
const shuffle = (arr) => {
  const len = arr?.length;
  if (!len) return arr;

  for (let i = 0; i < len; i++) {
    const random = Math.ceil(Math.random() * (len - 1));
    console.log(arr[random]);
    let temp = arr[random];

    arr[random] = arr[len - random];

    arr[len - random] = temp;
  }
  return arr;
};

let arr = [1, 2, 3, 4];

// console.log(shuffle(arr));

// 防抖函数
let timer = null;
const debounce = (value, delay) => {
  if (timer) {
    clearTimeout(timer);
    timer = null;
  }
  timer = setTimeout(() => {
    console.log(value);
  }, delay);
};
// 优化的解法
const createDebounce = (fn, delay = 500) => {
  let timer;

  return (...args) => {
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};

// debounce(12313);
// debounce(2345);

// 节流
const CreateThrottle = (fn, delay) => {
  let timer;

  return (...args) => {
    if (timer) {
      return;
    }

    timer = setTimeout(() => {
      console.log(args);
      fn.call(this, args);
      clearTimeout(timer);
      timer = null;
    }, delay);
  };
};

const throttle = CreateThrottle(() => {
  console.log("好的");
}, 1000);
// throttle();
// throttle();

// 13.函数珂里化

function add() {
  const params = [...arguments];

  function fn() {
    params.push(...arguments);
    console.log(params);
    return fn;
  }

  fn.prototype.toStr = () => {
    return params.reduce((sum, value) => value + sum);
  };

  return fn;
}

// console.log(add(1)(2)(3).toStr());

// 触底加载 https://www.jianshu.com/p/c59b2ccc963c
const reachBottom = (fn) => {
  window.addEventListener("scroll", () => {
    const clientHeight = document.documentElement.clientHeight;
    const scrollHeight = document.documentElement.scrollHeight;
    const scrollTop = document.documentElement.scrollTop;
    if (clientHeight + scrollTop >= scrollHeight) {
      // 触底
      fn();
    }
  });
};

// 一万条数据加载不卡 (将数据分成n小份，每份20条，分不同渲染)

const render = () => {
  const data = 100000;

  const pice = 20;

  const circle = Math.ceil(data / pice);

  const counter = 0;

  const Frament = () => {
    const siction = document.createDocumentFragment();
    for (let i = 0; i < pice; i++) {
      const li = document.createElement("li");
      li.innerText = `乱序第${Math.round(Math.random * data)}`;
      siction.appendChild(li);
    }
    counter++;
    if (counter < circle) {
      Frament();
    }
  };
  window.requestAnimationFrame(Frament);
};

// 385. 迷你语法分析器 (leetCode)
// 给定一个字符串 s 表示一个整数嵌套列表，实现一个解析它的语法分析器并返回解析的结果 NestedInteger 。

// 列表中的每个元素只可能是整数或整数嵌套列表
// 输入：s = "324",
// 输出：324
// 解释：你应该返回一个 NestedInteger 对象，其中只包含整数值 324。

const s = "[123,[456,[789]]]";
/**
 *输入：s = "[123,[456,[789]]]",
  输出：[123,[456,[789]]]
  解释：返回一个 NestedInteger 对象包含一个有两个元素的嵌套列表：
  1. 一个 integer 包含值 123
  2. 一个包含两个元素的嵌套列表：
    i.  一个 integer 包含值 456
    ii. 一个包含一个元素的嵌套列表
    a. 一个 integer 包含值 789
 * 
 */
const NestedInteger = (s) => {
  const arr = [];
  let str = "";
  for (let i = 0; i <= s.length; i++) {
    console.log(arr);
    if (s[i] === "[") {
      if (str) arr.push(str);
      if (s[i + 1] === "[") {
        arr.push([]);
      }
    } else if (s[i] === ",") {
      if (str) {
        arr[i].push(str);
        str = "";
      }
    } else if (s[i] === "]") {
    } else {
      str += s[i];
    }
  }

  return arr;
};

// /** 不如用自己的结题思维,但是可以用题锻炼自己的思维，和编码能力。 */
// function deserialize(s) {
//   let dummpy = [];
//   const layer = [];
//   layer.push(dummpy);
//   let str = "";
//   for (var i = 1; i < s.length; i++) {
//     console.log(layer);
//     if (s[i] === ",") {
//       if (str !== "") {
//         layer[layer.length - 1].push(str);
//       }
//       str = "";
//     } else if (s[i] === "[") {
//       let a = [];
//       layer[layer.length - 1].push(a);
//       layer.push(a);
//     } else if (s[i] === "]") {
//       if (str !== "") {
//         layer[layer.length - 1].push(str);
//       }
//       layer.pop();
//       str = "";
//     } else {
//       str += s[i];
//     }
//   }
//   return dummpy;
// }

// console.log(NestedInteger(s));

// 实现new 过程

// promise 并发器
/***JS 实现一个带并发限制的异步调度器 Scheduler，保证同时运行的任务最多有两个

addTask(1000,"1");
addTask(500,"2");
addTask(300,"3");
addTask(400,"4");
的输出顺序是：2 3 1 4

整个的完整执行流程：

一开始1、2两个任务开始执行
500ms时，2任务执行完毕，输出2，任务3开始执行
800ms时，3任务执行完毕，输出3，任务4开始执行
1000ms时，1任务执行完毕，输出1，此时只剩下4任务在执行
1200ms时，4任务执行完毕，输出4
 */
class Scheduler {
  constructor(limit) {
    this.queue = [];
    this.limit = limit;
    this.count = 0;
  }

  add(delay, params) {
    const request = () =>
      new Promise((resolve, reject) => {
        debugger;
        setTimeout(() => {
          console.log(params);
          resolve();
        }, delay);
      });
    this.queue.push(request);
  }
  start() {
    for (let i = 0; i < this.limit; i++) {
      this.request();
    }
  }

  request() {
    if (!this.queue.length) {
      return;
    }
    this.queue
      .shift()()
      .then(() => {
        this.request();
      });
  }
}

// const scheduler = new Scheduler(2);
// scheduler.add(1000, "1");
// scheduler.add(500, "2");
// scheduler.add(300, "3");
// scheduler.add(400, "4");
// scheduler.start();

/*** 给定一个只包括 '('，')'，'{'，'}'，'['，']' 的字符串 s ，判断字符串是否有效。 有效字符串需满足： */

const transStr = (s) => {
  if (!s) {
    return "请输入对称括号";
  }

  while (true) {
    let len = s.length;
    s = s.replace("{}", "").replace("[]", "").replace("()", "");
    console.log(s);
    if (s.length === len) {
      return len === 0;
    }
  }
};

/** 思路在哪里并且需要什么参数和变量 */
const transStr2 = (s) => {
  if (!s) {
    return "请输入对称的括号";
  }
  const obj = {
    "{": "}",
    "[": "]",
    "(": ")",
  };
  const stack = [];

  for (let i = 0; i < s.length; i++) {
    const chart = s[i];

    if (obj[chart]) {
      stack.push(chart);
    } else {
      const temp = stack.pop();
      console.log(stack, "--", chart, obj[temp]);
      if (!stack.length || obj[temp] !== chart) {
        return false;
      }
    }
  }

  return !stack.length;
};

console.log(transStr2("{[()]}"));

// 数组随机选取一个数（）
const pick = (arr) => {
  if (!arr.length) return "请输入数组";
  const index = Math.floor(Math.random * arr.length);
  return arr.splice(index, 1);
};

// 结构解析（）
const obj = {
  name: "zs",
  address: {
    shen: "huanggang",
    shi: "huagnga ",
  },
};

const { name, address } = obj ?? {};

const { shen, shi } = address ?? {};
console.log(shen, shi);

// // 用结构解析互换位置(直接报错)
// let a = "bears";
// let b = "tiger";
// const [b, a] = [a, b];
